package com.chennan.springaop.domain;

import com.chennan.redis.domain.service.RedisService;
import com.chennan.springaop.domain.annotation.PreventRepeatedSubmit;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.stereotype.Component;

import javax.validation.ConstraintViolationException;
import java.lang.reflect.Method;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

/**
 * @author chennan
 * @createTime 2021年07月23日 10:12:00
 *
 * 防止重复提交切面拦截
 */
@Aspect
@Component
@Slf4j
@EnableAspectJAutoProxy(proxyTargetClass = true)
public class PreventRepetitionAspect {

    @Autowired
    private RedisService redisService;

    /**
     * around
     *
     */
    @Around(value = "@annotation(com.chennan.springaop.domain.annotation.PreventRepeatedSubmit)")
    public Object excute(ProceedingJoinPoint joinPoint) throws Throwable {
        return validation(joinPoint);
    }

    public Object validation(ProceedingJoinPoint joinPoint) throws Throwable {

//        Long userId = LeadingSecurityContextUtil.getUserId();
        //获取当前登录用户id
//        if (null == userId) {
//            throw new LeadingServiceException(CommonError.USER_ORGANIZATION_MUST_NOT_NULL.getCode(),
//                    CommonError.USER_ORGANIZATION_MUST_NOT_NULL.getMessage());
//        }
        log.debug("Authentication is {}", 0000000000000000000000);
        // 获取当前拦截方法的对象
        // 获取类的字节码对象，通过字节码对象获取方法信息
        Class<?> targetClass = joinPoint.getTarget().getClass();
        // 获取方法签名(通过此签名获取目标方法信息)
        MethodSignature ms = (MethodSignature)joinPoint.getSignature();
        // 获取目标方法上的注解指定的操作名称
        Method targetMethod = targetClass.getDeclaredMethod(ms.getName(), ms.getParameterTypes());
        PreventRepeatedSubmit preventRepeatedSubmit =
                targetMethod.getAnnotation(PreventRepeatedSubmit.class);

        String prefix = preventRepeatedSubmit.keyPrefix();
        //如果没设置方法开头 这设置 类名称.方法名
        if ("".equals(prefix)) {
            prefix = targetClass.getName() + "." + targetMethod.getName();
        }
        //进行分布式锁处理，key设置为 方法key+当前登录人id
//        Object finishFlag = simpleDistributedLockService.doWithLockNoBlock(prefix + userId, preventRepeatedSubmit.lockTime(),
////                joinPoint::proceed);
//        if (finishFlag == null) {
//            log.debug("任务正在处理,不能重复处理");
//            throw new LeadingServiceException(CommonError.PREVENT_REPETITION.getCode(),
//                    CommonError.PREVENT_REPETITION.getMessage());
//        }
        Boolean aBoolean = redisService.setNX(prefix + 00000000000, UUID.randomUUID().toString(), preventRepeatedSubmit.lockTime(), TimeUnit.SECONDS);
        if(!aBoolean){
            throw new RuntimeException("设置失败，有人正在拉屎！！！");
        }
        Object[] args = joinPoint.getArgs();
        for (int i = 0; i < args.length; i++) {
            if(args[i] instanceof List){
                List list=(List)args[i];
                list.add("进入了拦截器中！！！！");
            }
        }
        return joinPoint.proceed(joinPoint.getArgs());
    }

}
